package Servicios;

import Singletons.Mensajes;
import Singletons.Restricciones;
import java.util.Calendar;
import java.util.Date;

public class ValidacionDatosEntrada {

    /**
     * <p>Verifica que la fecha pasada como argumento no halla pasado</p>
     * @param fecha Date
     * @return true si fecha es mayor a la fecha actual
     */
    public boolean fechaValida(Date fecha){
        Date hoy=new Date();
        return fecha.after(new Date(hoy.getYear(),hoy.getMonth(),hoy.getDate()-1,23,59,59));
    }
    
    /**
     * <p>Verifica que hInicio sea menor que la hora hFin</p>
     * @param hInicio String con un valor hora en el formato hh:mm
     * @param hFin String con un valor hora en el formato hh:mm
     * @return true si hInicio es menor que hFin, false de lo contrario
     */
    public boolean horasEnOrden(String hInicio,String hFin){
        int hI=Integer.parseInt(hInicio.substring(0,2));
        int hF=Integer.parseInt(hFin.substring(0,2));
        if(hF<hI)
            return false;
        if(hF>hI)
            return true;
        int mI=Integer.parseInt(hInicio.substring(3));
        int mF=Integer.parseInt(hFin.substring(3));
        return mF>mI;
    }

    /**
     * <p>Verifica si el string pasado como argumento cumple el formato de hora hh:mm</p>
     * @param hora String con la hora a verificar
     * @return true si el formato es correcto, false de lo contrario
     */
    public boolean formatoHoraCorrecto(String hora){
        if(hora.length()!=5)
            return false;
        try{
            if(hora.charAt(2)!=':')
                throw new NumberFormatException();
            int horas=Integer.parseInt(hora.substring(0, 2));
            if(horas<0 || horas>=24)
                throw new NumberFormatException();
            int minutos=Integer.parseInt(hora.substring(3));
            if(minutos<0 || minutos>=60)
                throw new NumberFormatException();
        }catch(NumberFormatException e){
            return false;
        }
        return true;
    }

    /**
     * <p>Verifica que el nombre pasado como argumento tenga el numero de caracteres permitido y no contenga caracteres especiales.</p>
     * @param nombre String
     * @return mensaje de error si el nombre no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String nombreCorrecto(String nombre){
        if(nombre.length()<Mensajes.LONGITUD_MINIMA_NOMBRE)
            return Mensajes.ERROR_LONGITUD_NOMBRE;
        if(nombre.length()>Mensajes.LONGITUD_MAXIMA_NOMBRE)
            return Mensajes.ERROR_LONGITUD_NOMBRE;
        for(int i=0;i<nombre.length();i++)
            if(nombre.charAt(i)>=45 && nombre.charAt(i)<=57)
                return Mensajes.ERROR_NOMBRE;
        char[] caracteresNoValidos={'=','!','@','#','$','%','^','&','*','(',')','{','}','[',']',';',':','.',',','<','>','?','~','+','-','_','\'','"'};
        for(int i=0;i<nombre.length();i++)
            for(int j=0;j<caracteresNoValidos.length;j++)
                if(nombre.charAt(i)==caracteresNoValidos[j])
                    return Mensajes.ERROR_NOMBRE;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que el correo pasado como argumento tenga el numero de caracteres permitido y solo contenga caracteres letras(minusculas).</p>
     * @param correo String
     * @return mensaje de error si el correo no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String correoCorrecto(String correo){
        if(correo.length()<Mensajes.LONGITUD_MINIMA_CORREO)
            return Mensajes.ERROR_LONGITUD_CORREO;
        if(correo.length()>Mensajes.LONGITUD_MAXIMA_CORREO)
            return Mensajes.ERROR_LONGITUD_CORREO;
        for(int i=0;i<correo.length();i++)
            if(correo.charAt(i)<97 || correo.charAt(i)>122)
                return Mensajes.ERROR_CORREO;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que el codigo pasado como argumento sea un numero y tenga la longitud adecuada.</p>
     * @param codigo String
     * @return mensaje de error si el codigo no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String codigoCorrecto(String codigo){
        try{
            Integer.parseInt(codigo);
        }catch(NumberFormatException e){
            return Mensajes.ERROR_CODIGO;
        }
        if(codigo.length()!=Mensajes.LONGITUD_CODIGO)
            return Mensajes.ERROR_LONGITUD_CODIGO;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que la cedula pasada como argumento sea un numero y tenga la longitud adecuada.</p>
     * @param cedula String
     * @return mensaje de error si la cedula no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String cedulaCorrecta(String cedula){
        try{
            Long.parseLong(cedula);
        }catch(NumberFormatException e){
            return Mensajes.ERROR_CEDULA;
        }
        if(cedula.length()<Mensajes.LONGITUD_MINIMA_CEDULA)
            return Mensajes.ERROR_LONGITUD_CEDULA;
        if(cedula.length()>Mensajes.LONGITUD_MAXIMA_CEDULA)
            return Mensajes.ERROR_LONGITUD_CEDULA;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que la cedcontrasenaula pasada como argumento tenga la longitud adecuada.</p>
     * @param contrasena String
     * @return mensaje de error si la contrasena no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String contrasenaCorrecta(String contrasena){
        if(contrasena.length()<Mensajes.LONGITUD_MINIMA_CONTRASENA)
            return Mensajes.ERROR_LONGITUD_CONTRASENA;
        if(contrasena.length()>Mensajes.LONGITUD_MAXIMA_CONTRASENA)
            return Mensajes.ERROR_LONGITUD_CONTRASENA;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que la dirección pasada como argumento tenga el numero de caracteres permitido y no contenga caracteres especiales.</p>
     * @param dirección String
     * @return mensaje de error si la dirección no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String direccionCorrecta(String direccion){
        if(direccion.length()<Mensajes.LONGITUD_MINIMA_DIRECCION)
            return Mensajes.ERROR_LONGITUD_DIRECCION;
        if(direccion.length()>Mensajes.LONGITUD_MAXIMA_DIRECCION)
            return Mensajes.ERROR_LONGITUD_DIRECCION;
        char[] caracteresNoValidos={'=','!','@','$','%','^','&','*','(',')','{','}','[',']',';',':',',','<','>','?','~','+','_','\'','"'};
        for(int i=0;i<direccion.length();i++)
            for(int j=0;j<caracteresNoValidos.length;j++)
                if(direccion.charAt(i)==caracteresNoValidos[j])
                    return Mensajes.ERROR_DIRECCION;
        return Mensajes.ENTRADA_VALIDA;
    }

    /**
     * <p>Verifica que el telefono pasado como argumento sea un numero y tenga la longitud adecuada.</p>
     * @param telefono String
     * @return mensaje de error si el telefono no cumple las especificaciones, mensaje de validacion si si las cumple
     */
    public String telefonoCorrecto(String telefono){
        try{
            Long.parseLong(telefono);
        }catch(NumberFormatException e){
            return Mensajes.ERROR_TELEFONO;
        }
        if(telefono.length()<Mensajes.LONGITUD_MINIMA_TELEFONO)
            return Mensajes.ERROR_LONGITUD_TELEFONO;
        if(telefono.length()>Mensajes.LONGITUD_MAXIMA_TELEFONO)
            return Mensajes.ERROR_LONGITUD_TELEFONO;
        return Mensajes.ENTRADA_VALIDA;
    }

    public String validarHoras(String horario, int horaInicio, int horaFin, int minInicio, int minFin) {
        //hh:mm-hh:mm
        int horaIniHorario = Integer.parseInt(horario.substring(0, 2));
        int minIniHorario = Integer.parseInt(horario.substring(3, 5));
        int horaFinHorario = Integer.parseInt(horario.substring(6, 8));
        int minFinHorario = Integer.parseInt(horario.substring(9,11));
        Calendar horarioInicio = Calendar.getInstance();
        horarioInicio.set(Calendar.HOUR_OF_DAY,horaIniHorario);
        horarioInicio.set(Calendar.MINUTE,minIniHorario);
        Calendar horarioFin = Calendar.getInstance();
        horarioFin.set(Calendar.HOUR_OF_DAY,horaFinHorario);
        horarioFin.set(Calendar.MINUTE,minFinHorario);
        Calendar Inicio = Calendar.getInstance();
        Inicio.set(Calendar.HOUR_OF_DAY, horaInicio);
        Inicio.set(Calendar.MINUTE, minInicio);
        Calendar Fin = Calendar.getInstance();
        Fin.set(Calendar.HOUR_OF_DAY, horaFin);
        Fin.set(Calendar.MINUTE, minFin);
        if(Inicio.after(Fin))
            return "La hora de inicio no puede ser mayor a la de fin.";
        if(horarioInicio.after(Inicio))
            return "Hora de inicio invalida.";
        if(horarioInicio.after(Fin))
            return "Hora de fin invalida.";
        if(horarioFin.before(Inicio))
            return "Hora de inicio invalida.";
        if(horarioFin.before(Fin))
            return "Hora de fin invalida.";
        Long tiempoFin= Fin.getTimeInMillis();
        Long tiempoInicio= Inicio.getTimeInMillis();
        Long dif = tiempoFin - tiempoInicio;
        Long minutos = dif/1000/60;

        Restricciones r = Restricciones.getInstance();
        int tamañoBloque = r.getTamañoBloque();
        double numBloques = minutos/tamañoBloque;
        if(numBloques<r.getMinimoBloquesRE())
            return "Tiempo de reserva muy pequeño";
        if(numBloques>r.getMaximoBloquesRE())
            return "Tiempo de reserva muy pequeño";

        return null;

    }

    public boolean validarFechaReservaEstacion(Calendar fecha) {
        Restricciones r = Restricciones.getInstance();
        int max = r.getTiempoMaximoRE();
        Calendar fechaLimite = Calendar.getInstance();
        fechaLimite.add(Calendar.DAY_OF_YEAR, max);
        if(fechaLimite.after(fecha))
            return true;
        else{
            return false;
        }
    }

}